﻿<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory">第 2 章，基本概念</title>
<link rel="stylesheet" href="css/espertech.css" type="text/css">
	<meta xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" name="generator" content="DocBook XSL-NS Stylesheets V1.74.0">
		<meta xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" http-equiv="Content-Type" content="text/html; charset=UTF-8">
			<link rel="home" href="index.html" title="Esper Reference">
				<link rel="up" href="index.html" title="Esper Reference">
					<link rel="prev" href="gettingstarted.html" title="Chapter 1. Getting Started">
						<link rel="next" href="event_representation.html" title="Chapter 3. Event Representations">
</head>

<body>
	<p xmlns:d="http://docbook.org/ns/docbook" id="title">
		<a href="./index.html" class="site_href"><strong>www.espertech.com</strong></a><a href="http://www.espertech.com/esper/esper-documentation/" class="doc_href"><strong>文档</strong></a>
	</p>
	<ul xmlns:d="http://docbook.org/ns/docbook" class="docnav">
		<li class="previous"><a accesskey="p" href="gettingstarted.html"><strong>上一页</strong></a></li>
		<li class="next"><a accesskey="n" href="event_representation.html"><strong>下一页</strong></a></li>
	</ul>
	<div class="chapter" lang="en-US">
		<div class="titlepage">
			<div>
				<div>
					<h2 class="title"><a id="processingmodel"></a>第2章. 基本概念</h2>
				</div>
			</div>
		</div>
		<div class="toc">
			<dl>
				<dt><a href="processingmodel.html#processingmodel_intro">2.1. 简介</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicselect">2.2. 基本选择语句</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicaggregation">2.3. 基本聚合</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicfilter">2.4. 基本过滤</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicfilterwithagg">2.5. 基本过滤和聚合</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicwindow">2.6. 基本数据窗口</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicwindowagg">2.7. 基本数据窗口和聚合</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicfilterwindowagg">2.8. 基本过滤、数据窗口和聚合</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicwhereclause">2.9. 基本WHERE子句</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basictimewindow">2.10. 基本时间窗口和聚合</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicpartition">2.11. 基本分区语句</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicoutputlimited">2.12. 基本输出速率限制语句</a></dt>
				<dt><a href="processingmodel.html#processingmodel_basicpartitionedandoutputlimited">2.13. 基本分区和输出速率限制语句</a></dt>
				<dt><a href="processingmodel.html#processingmodel_infra">2.14. 基本命名窗口和表</a></dt>
				<dd>
					<dl>
						<dt><a href="processingmodel.html#processingmodel_infra_namedwindow">2.14.1. 命名窗口</a></dt>
						<dt><a href="processingmodel.html#processingmodel_infra_table">2.14.2. 表</a></dt>
					</dl>
				</dd>
				<dt><a href="processingmodel.html#processingmodel_aggregation">2.15. 基本聚合语句类型</a></dt>
				<dd>
					<dl>
						<dt><a href="processingmodel.html#processingmodel_aggregation_batch_unagg">2.15.1. 非聚合和非分组</a></dt>
						<dt><a href="processingmodel.html#processingmodel_aggregation_batch_full_agg">2.15.2. 完全聚合和非分组</a></dt>
						<dt><a href="processingmodel.html#processingmodel_aggregation_batch_event_agg">2.15.3. 聚合和非分组</a></dt>
						<dt><a href="processingmodel.html#processingmodel_aggregation_batch_group_agg">2.15.4. 完全聚合和分组</a></dt>
						<dt><a href="processingmodel.html#processingmodel_aggregation_batch_event_agg_group">2.15.5. 聚合和分组</a></dt>
					</dl>
				</dd>
				<dt><a href="processingmodel.html#processingmodel_matchrecognizepattern">2.16. 基本匹配识别模式</a></dt>
				<dt><a href="processingmodel.html#processingmodel_eplpattern">2.17. 基本EPL模式</a></dt>
				<dt><a href="processingmodel.html#processingmodel_indexes">2.18. 基本索引</a></dt>
				<dd>
					<dl>
						<dt><a href="processingmodel.html#processingmodel_indexes_kinds">2.18.1. 索引类型</a></dt>
						<dt><a href="processingmodel.html#processingmodel_indexes_filterindexes">2.18.2. 过滤索引</a></dt>
						<dt><a href="processingmodel.html#processingmodel_indexes_eventindexes">2.18.3. 事件索引</a></dt>
					</dl>
				</dd>
				<dt><a href="processingmodel.html#processingmodel_3valuedlogic">2.19. 基本空值处理</a></dt>
			</dl>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_intro"></a>2.1. 简介</h2>
					</div>
				</div>
			</div>
			<p>
				对于NEsper .NET，另请参阅 <a class="xref" href="appendix_dotnet.html#appendix_dotnet_processingmodel_intro" title="J.12. .NET基本概念">第J.12节，“.NET基本概念”</a>。
			</p>
			<p>语句是用于分析事件和时间并检测情况的连续查询。</p>
			<p>您可以通过编译和部署包含语句的模块、发送事件和推进时间，以及通过回调接收输出或轮询当前结果来与Esper进行交互。</p>
			<div class="table">
				<a id="d0e641"></a>
				<p class="title">
					<b>表2.1. 与Esper交互</b>
				</p>
				<div class="table-contents">
					<table summary="与Esper交互" border="1">
						<colgroup>
							<col>
								<col>
						</colgroup>
						<thead>
							<tr>
								<th>操作</th>
								<th>方法</th>
							</tr>
						</thead>
						<tbody>
							<tr>
								<td>EPL</td>
								<td>首先，编译和部署语句，请参考 <a class="xref" href="epl_clauses.html" title="第5章. EPL参考：子句">第5章, <i>EPL参考：子句</i></a>、<a class="xref" href="apicompiler.html" title="第15章. 编译器参考">第15章, <i>编译器参考</i></a> 和 <a class="xref" href="apiruntime.html" title="第16章. 运行时参考">第16章, <i>运行时参考</i></a>。
								</td>
							</tr>
							<tr>
								<td>回调</td>
								<td>其次，附加您的应用程序提供的可执行代码以接收输出，请参考 <a class="xref" href="apiruntime.html#apiruntime-statement-receiveresults" title="表16.2. 接收语句结果的选项">表16.2，“接收语句结果的选项”</a>。
								</td>
							</tr>
							<tr>
								<td>事件</td>
								<td>接下来，使用运行时API发送事件，请参考 <a class="xref" href="apiruntime.html#apiruntime-eventservice" title="16.6. 使用EPEventService处理事件和时间">第16.6节，“使用EPEventService处理事件和时间”</a>。
								</td>
							</tr>
							<tr>
								<td>时间</td>
								<td>接下来，使用运行时API或系统时间推进时间，请参考 <a class="xref" href="apiruntime.html#apiruntime-time" title="16.9. 控制时间记录">第16.9节，“控制时间记录”</a>。
								</td>
							</tr>
						</tbody>
					</table>
				</div>
			</div>
			<br class="table-break">
				<p>运行时包含如下语句：</p>
				<div class="figure">
					<a id="processingmodel_into_querycontainerpic"></a>
					<div class="figure-contents">
						<div class="mediaobject" align="center">
							<img src="images/refdoc_procmodel_querycontainer.png" align="middle" alt="运行时是一个语句容器">
						</div>
					</div>
					<p class="title">
						<b>图2.1. 运行时是一个语句容器</b>
					</p>
				</div> <br class="figure-break">
					<p>
						语句可以进行分区。一个分区语句可以有多个分区。例如，建筑物中的每个房间可以有一个分区。 对于一个有10个房间的建筑物，您可以有一个具有10个分区的语句。请参考 <a class="xref" href="context.html" title="第4章. 上下文和上下文分区">第4章, <i>上下文和上下文分区</i></a>。
					</p>
					<p>未分区的语句隐式地有一个分区。部署未分区的语句时，运行时会分配单个分区。取消部署未分区的语句时，运行时会销毁该分区。</p>
					<p>分区（或“上下文分区”）是运行时保存状态的地方。在上面的图中有三个未分区的语句和一个有三个分区的分区语句。</p>
					<p>
						接下来的部分将讨论各种易于理解的语句。 这些部分将说明语句的行为、运行时传递给回调的信息（输出）以及运行时为语句记住的信息（“状态”，所有状态都存在于一个分区中）。 示例语句假设存在一个名为 <code class="literal">Withdrawal</code> 的事件类型，该类型具有 <code class="literal">account</code> 和 <code class="literal">amount</code> 属性。
					</p>
		</div>

		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicselect"></a>2.2. 基本选择语句</h2>
					</div>
				</div>
			</div>
			<p>
				此语句选择所有的 <code class="literal">Withdrawal</code> 事件。
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select * from Withdrawal</pre>
			<p>
				当一个新的 <code class="literal">Withdrawal</code> 事件到达时，运行时会将到达的事件原封不动地（并且是相同的对象引用）传递给回调函数。 之后，运行时实际上会忘记当前事件。
			</p>
			<p>
				下面的图表显示了随着时间推移到达的一系列 <code class="literal">Withdrawal</code> 事件（1到6）。 在图中， <code class="literal">W</code> <sub>n</sub>代表特定的到达的 <code class="literal">Withdrawal</code> 事件。括号中的数字是提款金额。
			</p>
			<div class="figure">
				<a id="processingmodel_into_basicselect"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicselect.png" align="middle" alt="EPL选择语句示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.2. EPL选择语句示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>对于此语句，运行时不记住任何信息，也不记住任何事件。运行时根本不需要记住任何信息的语句是无状态语句（“无状态”语句）。</p>
				<p>术语“插入流”是指到达的新事件流的名称。在此示例中，插入流是到达的提款事件流。</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicaggregation"></a>2.3. 基本聚合</h2>
					</div>
				</div>
			</div>
			<p>
				聚合函数是一种将多个事件组合在一起以形成单个值的函数。更多信息请参见 <a class="xref" href="functionreference.html#epl-function-aggregation" title="10.2. 聚合函数">第10.2节，“聚合函数”</a>。
			</p>
			<p>此语句选择所有提款事件的计数和总金额。</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select count(*), sum(amount) from Withdrawal</pre>
			<p>
				当一个新的 <code class="literal">Withdrawal</code> 事件到达时，运行时会增加计数，并将金额添加到累计总额中。它将新的计数和总额传递给回调函数。 之后，运行时实际上会忘记当前事件，并且根本不记住任何事件，但会记住当前的计数和总额。
			</p>
			<div class="figure">
				<a id="processingmodel_into_basicaggregation"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicaggregation.png" align="middle" alt="EPL选择语句示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.3. EPL选择语句示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					在这里，运行时只记住当前的事件数量和总金额。 计数是一个长整型值，总额是一个双精度型值（假设 <code class="literal">amount</code> 是一个双精度值，总额可以是适用的 <code class="literal">BigDecimal</code> ）。 此语句不是无状态的，状态由一个长整型值和一个双精度型值组成。
				</p>
				<p>
					当一个新的 <code class="literal">Withdrawal</code> 事件到达时，运行时将计数增加一，并将金额添加到累计总额中。运行时不会重新计算计数和总额，因为它不记住事件。 一般来说，运行时不会重新计算聚合（除非另有说明）。相反，运行时将数据添加（增加、输入、累积）到聚合状态中，并从聚合状态中减去（减少、移除、降低、减少）数据。
				</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicfilter"></a>2.4. 基本过滤</h2>
					</div>
				</div>
			</div>
			<p>
				将过滤表达式放在事件类型名称后面的括号中。更多信息请参见 <a class="xref" href="epl_clauses.html#epl-from-clause-filter" title="5.4.1. 基于过滤的事件流">第5.4.1节，“基于过滤的事件流”</a>。
			</p>
			<p>
				此语句选择金额为200或更高的 <code class="literal">Withdrawal</code> 事件：
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select * from Withdrawal(amount &gt;= 200)</pre>
			<p>
				当一个金额为200或更高的新的 <code class="literal">Withdrawal</code> 事件到达时，运行时会将到达的事件传递给回调函数。
			</p>
			<div class="figure">
				<a id="processingmodel_into_basicfilter"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicfilter.png" align="middle" alt="EPL过滤示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.4. EPL过滤示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>对于此语句，运行时不记住任何信息，也不记住任何事件。</p>
				<p>
					你可能会问，对于金额小于200的 <code class="literal">Withdrawal</code> 事件会发生什么。答案是该语句本身甚至不会看到这样的事件。这是因为运行时知道立即丢弃此类事件， 并且该语句甚至不知道有这样的事件。运行时通过语句分析、规划和合适的数据结构非常快速地丢弃不需要的事件。
				</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicfilterwithagg"></a>2.5. 基本过滤和聚合</h2>
					</div>
				</div>
			</div>
			<p>
				此语句选择金额为200或更高的 <code class="literal">Withdrawal</code> 事件的计数和总金额：
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select count(*), sum(amount) from Withdrawal(amount &gt;= 200)</pre>
			<p>
				当一个金额为200或更高的新的 <code class="literal">Withdrawal</code> 事件到达时，运行时会增加计数，并将金额添加到累计总额中。运行时将计数和总额传递给回调函数。
			</p>
			<div class="figure">
				<a id="processingmodel_into_basicfilterwithagg"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicfilteragg.png" align="middle" alt="EPL过滤和聚合示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.5. EPL过滤和聚合示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					在此示例中，运行时只记住计数和总额，并且同样不记住事件。运行时会丢弃金额小于200的 <code class="literal">Withdrawal</code> 事件。
				</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicwindow"></a>2.6. 基本数据窗口</h2>
					</div>
				</div>
			</div>
			<p>
				“数据窗口”，或简称为“窗口”，用于为了聚合、连接、匹配识别模式、子查询、通过API迭代和输出快照而保留事件。 数据窗口定义要保留的事件子集。例如，长度窗口保留最后N个事件，时间窗口保留过去N秒的事件。 详细信息请参见 <a class="xref" href="epl-views.html" title="第14章. EPL参考：数据窗口">第14章, <i>EPL参考：数据窗口</i></a>。
			</p>
			<p>
				此语句选择所有的 <code class="literal">Withdrawal</code> 事件，并指示运行时记住最后五个事件。
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select * from Withdrawal#length(5)</pre>
			<p>
				当一个新的 <code class="literal">Withdrawal</code> 事件到达时，运行时会将该事件添加到长度窗口中。它还会将相同的事件传递给回调函数。
			</p>
			<div class="figure">
				<a id="processingmodel_into_basicdatawindow"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicwindow.png" align="middle" alt="EPL基本数据窗口示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.6. EPL基本数据窗口示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					当事件W<sub>6</sub>到达时，事件W<sub>1</sub>离开长度窗口。我们使用术语“过期”来表示一个事件离开数据窗口。 我们使用术语“移除流”来描述离开数据窗口的事件流。
				</p>
				<p>运行时总共记住最多五个事件（最后五个事件）。在语句开始时，数据窗口为空。 就其本身而言，保留最后五个事件可能听起来没有什么用。但是，例如，与连接、子查询或匹配识别模式结合使用时，数据窗口会告诉运行时您想要查询哪些事件。</p>
				<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="note">
					<h2>注意</h2> 默认情况下，运行时仅将插入流传递给监听器和观察者。 EPL支持在select和insert-into子句中使用可选的 <code class="literal">istream</code> 、 <code class="literal">irstream</code> 和 <code class="literal">rstream</code> 关键字来控制传递哪些流，请参见 <a class="xref" href="epl_clauses.html#epl-select-using-istream-rstream" title="5.3.7. 选择插入和移除流事件">第5.3.7节，“选择插入和移除流事件”</a>。
				</div>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicwindowagg"></a>2.7. 基本数据窗口和聚合</h2>
					</div>
				</div>
			</div>
			<p>
				此语句输出最后五个 <code class="literal">Withdrawal</code> 事件的计数和总数。
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select count(*), sum(amount) from Withdrawal#length(5)</pre>
			<p>
				当一个新的 <code class="literal">Withdrawal</code> 事件到达时，运行时会将该事件添加到长度窗口中，将计数增加一，并将金额添加到当前总额中。 当一个 <code class="literal">Withdrawal</code> 事件离开数据窗口时，运行时会将计数减一，并从当前总额中减去其金额。 它将累计计数和总额传递给回调函数。
			</p>
			<div class="figure">
				<a id="processingmodel_into_basicwindowagg"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicwindowagg.png" align="middle" alt="EPL基本数据窗口和聚合示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.7. EPL基本数据窗口和聚合示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					在事件W<sub>6</sub>到达之前，当前计数为五，累计总额为1000。当事件W<sub>6</sub>到达时，会发生以下情况：
				</p>
				<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="orderedlist">
					<ol>
						<li>
							<p>
								运行时确定事件W<sub>1</sub>离开长度窗口。
							</p>
						</li>
						<li>
							<p>
								为了处理新事件W<sub>6</sub>，运行时将计数增加一，并将300添加到累计总额中。
							</p>
						</li>
						<li>
							<p>
								为了处理过期事件W<sub>1</sub>，运行时将计数减一，并从累计总额中减去500。
							</p>
						</li>
						<li>
							<p>
								输出结果为计数为五，总额为800，即 <code class="literal">1000 + 300 - 500</code> 的结果。
							</p>
						</li>
					</ol>
				</div>
				<p>运行时将插入流事件添加（增加、输入、累积）到聚合状态中，并从聚合状态中减去（减少、移除、降低、减少）移除流事件。 因此，它以增量方式维护聚合状态。</p>
				<p>对于此语句，一旦计数达到5，计数将始终保持为5。</p>
				<p>运行时为此语句记住的信息是最后五个事件以及当前的长整型计数和双精度型总额。</p>
				<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="tip">
					<h2>提示</h2>
					<p>
						对于聚合语句，使用 <code class="literal">irstream</code> 关键字来接收当前以及先前的聚合值。
					</p>
				</div>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicfilterwindowagg"></a>2.8. 基本过滤、数据窗口和聚合</h2>
					</div>
				</div>
			</div>
			<p>以下语句输出最后五个金额至少为200的`Withdrawal`事件的计数和总计：</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">
select count(*), sum(amount) from Withdrawal(amount>=200)#length(5)
    </pre>
			<p>当一个新的`Withdrawal`事件到达时，并且只有该事件的金额为200或更多时，运行时才会将该事件添加到长度窗口中，将计数增加1，并将金额添加到当前总计中。 当一个`Withdrawal`事件离开数据窗口时，运行时会将计数减少1，并从当前总计中减去其金额。 它将运行计数和总计传递给回调函数。</p>
			<div class="figure">
				<a id="processingmodel_into_basicfilterwindowagg"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicfilterwindowagg.png" align="middle" alt="EPL基本过滤、数据窗口和聚合示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.8. EPL基本过滤、数据窗口和聚合示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicwhereclause"></a>2.9. 基本WHERE子句</h2>
					</div>
				</div>
			</div>
			<p>对于没有数据窗口的语句，WHERE子句的行为与放在括号中的过滤表达式相同。</p>
			<p>由于没有数据窗口，以下两个语句完全等效（`....`表示任何选择子句表达式）：</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">
select .... from Withdrawal(amount > 200)
// 等效于
select .... from Withdrawal where amount > 200
    </pre>
			<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="note">
				<h2>注意</h2>
				<p>在EPL中，WHERE子句通常用于连接或子查询中的相关性操作。过滤表达式应紧跟在事件类型名称后的括号中。</p>
			</div>
			<p>
				下一个语句对`Withdrawal`事件应用WHERE子句。在 <a class="xref" href="epl_clauses.html#epl-where-clause" title="5.5. 指定搜索条件：WHERE子句">第5.5节，“指定搜索条件：WHERE子句”</a> 中会更详细地讨论WHERE子句。
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">
select * from Withdrawal#length(5) where amount >= 200
    </pre>
			<p>WHERE子句适用于新事件和过期事件。只有通过WHERE子句的事件才会传递给回调函数。</p>
			<div class="figure">
				<a id="processingmodel_into_basicwhere"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicwhere.png" align="middle" alt="EPL基本WHERE子句示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.9. EPL基本WHERE子句示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basictimewindow"></a>2.10. 基本时间窗口和聚合</h2>
					</div>
				</div>
			</div>
			<p>
				时间窗口是一种数据窗口，它将指定的时间间隔延伸到过去。有关时间窗口的更多信息，请参见 <a class="xref" href="epl-views.html#view-win-time" title="14.3.3. 时间窗口（time或win:time）">第14.3.3节，“时间窗口（time或win:time）”</a>。
			</p>
			<p>下一个语句选择过去4秒内`Withdrawal`事件的计数和总金额。</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">
select count(*), sum(amount) as total from Withdrawal#time(4)
    </pre>
			<p>该图表从给定时间`$t$`开始，显示在`$t + 4$`和`$t + 5$`秒等时刻时间窗口的内容。</p>
			<div class="figure">
				<a id="processingmodel_into_basictimewindow"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basictimewindowagg.png" align="middle" alt="EPL基本时间窗口示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.10. EPL基本时间窗口示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>图表所示的活动如下：</p>
				<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="orderedlist">
					<ol>
						<li>
							<p>在时间`$t + 4$`秒时，事件`$W_1$`到达，输出的计数为1，总计为500。</p>
						</li>
						<li>
							<p>在时间`$t + 5$`秒时，事件`$W_2$`到达，输出的计数为2，总计为600。</p>
						</li>
						<li>
							<p>在时间`$t + 6.5$`秒时，事件`$W_3$`到达，输出的计数为3，总计为800。</p>
						</li>
						<li>
							<p>在时间`$t + 8$`秒时，事件`$W_1$`过期，输出的计数为2，总计为300。</p>
						</li>
					</ol>
				</div>
				<p>对于此语句，运行时会记住过去4秒内的`Withdrawal`事件，以及长整型的计数和双精度型的总金额。</p>
				<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="tip">
					<h2>提示</h2>
					<p>时间可以精确到毫秒或微秒。</p>
				</div>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicpartition"></a>2.11. 基本分区语句</h2>
					</div>
				</div>
			</div>
			<p>到目前为止讨论的语句都没有进行分区。未分区的语句隐式地有一个分区。 部署未分区的语句时，运行时会分配单个分区，当您的应用程序取消部署该语句时，运行时会销毁该分区。</p>
			<p>
				分区语句对于批处理、会话、重置以及分析的启动/停止很有用。对于分区语句，您必须指定一个上下文。上下文定义了如何分配和销毁分区。 有关分区语句和上下文的更多信息，请参见 <a class="xref" href="context.html" title="第4章. 上下文和上下文分区">第4章, <i>上下文和上下文分区</i></a>。
			</p>
			<p>我们将创建一个立即启动并在四秒后结束的单个分区：</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">create context Batch4Seconds start @now end after 4 sec</pre>
			<p>
				下一个语句选择自上次重置（重置时间为 <code class="literal">t</code> 、 <code class="literal">t+4</code> 、 <code class="literal">t+8</code> 等等）以来到达的 <code class="literal">Withdrawal</code> 事件的计数和总金额，每四秒重置一次：
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">context Batch4Seconds select count(*), total(amount) from Withdrawal</pre>
			<div class="figure">
				<a id="processingmodel_into_basicpartitioned"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicpartitioned.png" align="middle" alt="EPL基本分区语句示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.11. EPL基本分区语句示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					在时间 <code class="literal">t + 4 seconds</code> 和 <code class="literal">t + 8 seconds</code> 时，运行时会销毁当前分区。这会丢弃当前的计数和累计总额。 运行时会立即分配一个新分区，计数和总额将重新从零开始。
				</p>
				<p>对于此语句，运行时只记住计数和累计总额，以及分区的存活时间。</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicoutputlimited"></a>2.12. 基本输出速率限制语句</h2>
					</div>
				</div>
			</div>
			<p>
				之前的所有语句都有连续的输出。换句话说，在之前的每个语句中，输出都是由于新事件的到达而产生的。 如 <a class="xref" href="epl_clauses.html#epl-output-rate" title="5.7. 稳定和控制输出：输出子句">第5.7节，“稳定和控制输出：输出子句”</a> 中所述，使用输出速率限制在条件发生时进行输出。
			</p>
			<p>
				下一个语句每四秒输出所有 <code class="literal">Withdrawal</code> 事件的最新计数和总计：
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select count(*), total(amount) from Withdrawal output last every 4 seconds</pre>
			<div class="figure">
				<a id="processingmodel_into_basicoutputlimited"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicoutputratelimited.png" align="middle" alt="基本输出速率限制语句示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.12. 基本输出速率限制语句示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					在时间 <code class="literal">t + 4 seconds</code> 和 <code class="literal">t + 8 seconds</code> 时，运行时会将最新的聚合值输出给回调函数。
				</p>
				<p>对于此语句，运行时只记住计数和累计总额，以及何时应进行输出。</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_basicpartitionedandoutputlimited"></a>2.13. 基本分区和输出速率限制语句</h2>
					</div>
				</div>
			</div>
			<p>使用带有输出速率限制的分区语句来进行输出和重置。这使您能够形成批次，分析一个批次，然后忘记与该批次相关的所有状态，接着处理下一个批次。</p>
			<p>
				下一个语句选择在最后四秒内到达的 <code class="literal">Withdrawal</code> 事件的计数和总金额，并在四秒结束时输出，输出后重置：
			</p>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">create context Batch4Seconds start @now end after 4 sec</pre>
			<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">context Batch4Seconds select count(*), total(amount) from Withdrawal output last when terminated</pre>
			<div class="figure">
				<a id="processingmodel_into_basicpartitionedandoutputlimited"></a>
				<div class="figure-contents">
					<div class="mediaobject" align="center">
						<img src="images/refdoc_procmodel_basicpartitionedandoutputlimited.png" align="middle" alt="基本分区和输出速率限制语句示例输入和输出流">
					</div>
				</div>
				<p class="title">
					<b>图2.13. 基本分区和输出速率限制语句示例输入和输出流</b>
				</p>
			</div>
			<br class="figure-break">
				<p>
					在时间 <code class="literal">t + 4 seconds</code> 和 <code class="literal">t + 8 seconds</code> 时，运行时会将最新的聚合值输出给回调函数，并重置当前的计数和总计。
				</p>
				<p>对于此语句，运行时只记住计数和累计总额，以及何时应进行输出和分区的存活时间。</p>
		</div>
		<div class="sect1" lang="en-US">
			<div class="titlepage">
				<div>
					<div>
						<h2 class="title"><a id="processingmodel_infra"></a>2.14. 基本命名窗口和表</h2>
					</div>
				</div>
			</div>
			<p>命名窗口管理事件的一个子集，以供其他语句使用。它们可以被多个语句进行选择、插入、删除和更新操作。</p>
			<p>表与命名窗口类似，但表是按主键进行组织的，并且包含行和列。表可以共享聚合状态，而命名窗口仅共享它们所管理的事件子集。</p>
			<p>
				两者的文档链接为 <a class="xref" href="nwtable.html" title="第6章. EPL参考：命名窗口和表">第6章, <i>EPL参考：命名窗口和表</i></a>。命名窗口和表可以通过API以及面向内部的JDBC驱动程序使用即发即弃（fire-and-forget）查询进行查询。
			</p>
			<div class="sect2" lang="en-US">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title"><a id="processingmodel_infra_namedwindow"></a>2.14.1. 命名窗口</h3>
						</div>
					</div>
				</div>
				<p>
					命名窗口声明一个用于保存事件的窗口，并且在 <code class="literal">from</code> 子句中包含该命名窗口名称的其他语句会隐式地聚合或分析同一组事件。 这消除了为不同的EPL语句多次声明相同窗口的需要。
				</p>
				<p>下面的图示解释了命名窗口的工作原理。</p>
				<div class="figure">
					<a id="processingmodel_infra_namedwindow_drawing"></a>
					<div class="figure-contents">
						<div class="mediaobject" align="center">
							<img src="images/refdoc_procmodel_namedwindow.png" align="middle" alt="命名窗口机制">
						</div>
					</div>
					<p class="title">
						<b>图2.14. 命名窗口机制</b>
					</p>
				</div>
				<br class="figure-break">
					<p>
						<span class="strong"><strong>步骤#1</strong></span> 如下创建一个命名窗口：
					</p> <pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">create window WithdrawalWindow#time(10) as Withdrawal</pre>
					<p>
						命名窗口的名称是 <code class="literal">WithdrawalWindow</code> ，它将保存最近10秒内的 <code class="literal">Withdrawal</code> 事件（ <code class="literal">#time(10) as Withdrawal</code> ）。
					</p>
					<p>
						作为步骤#1的结果，运行时会分配一个命名窗口来保存10秒内的 <code class="literal">Withdrawal</code> 事件。在图中，命名窗口中填充了一些事件。通常，命名窗口开始时是空的，但里面已经有一些框看起来更好。
					</p>
					<p>
						<span class="strong"><strong>步骤#2</strong></span> 创建一个EPL语句以插入到命名窗口中：
					</p> <pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">on Withdrawal merge WithdrawalWindow insert select *</pre>
					<p>
						这告诉运行时，当 <code class="literal">Withdrawal</code> 事件到达时，它必须与 <code class="literal">WithdrawalWindow</code> 合并并插入该事件。现在运行时等待 <code class="literal">Withdrawal</code> 事件的到达。
					</p>
					<p>
						<span class="strong"><strong>步骤#3</strong></span> 创建一个EPL语句，该语句计算由命名窗口控制的事件子集的平均提款金额：
					</p> <pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select avg(amount) as avgAmount from WithdrawalWindow</pre>
					<p>
						作为步骤#3的结果，运行时会分配状态以保存当前的平均值。该状态由一个 <code class="literal">count</code> 字段和一个 <code class="literal">sum</code> 字段组成，用于计算运行平均值。 它确定命名窗口当前为空，并将 <code class="literal">count</code> 设置为零，将 <code class="literal">sum</code> 设置为空（如果命名窗口已经填充，则它将通过迭代确定 <code class="literal">count</code> 和 <code class="literal">sum</code> ）。 在内部，它还会向命名窗口注册一个消费者回调函数，以接收插入和删除的事件（插入流和删除流）。回调函数在图中显示为虚线。
					</p>
					<p>
						<span class="strong"><strong>在步骤#4中</strong></span> 假设一个 <code class="literal">Withdrawal</code> 事件到达，其账号为 <code class="literal">0001</code> ，金额为 <code class="literal">5000</code> 。 运行时执行 <code class="literal">on Withdrawal merge WithdrawalWindow insert select *</code> ，从而将该事件添加到时间窗口中。 运行时会为所有消费者调用插入流回调函数（虚线，内部管理的回调函数）。 计算平均金额的消费者会接收到回调函数和新插入的事件。它将 <code class="literal">count</code> 字段增加1，并将 <code class="literal">sum</code> 字段增加 <code class="literal">5000</code> 。 该语句的输出 <code class="literal">avgAmount</code> 为 <code class="literal">5000</code> 。
					</p>
					<p>
						<span class="strong"><strong>在步骤#5中</strong></span>，即步骤#4发生10秒后，账号为 <code class="literal">0001</code> 且金额为 <code class="literal">5000</code> 的 <code class="literal">Withdrawal</code> 事件离开时间窗口。 运行时会为所有消费者调用删除流回调函数（虚线，内部管理的回调函数）。 计算平均金额的消费者会接收到回调函数和新删除的事件。它将 <code class="literal">count</code> 字段减少1，并将 <code class="literal">sum</code> 设置为空，且 <code class="literal">count</code> 为零。 该语句的输出 <code class="literal">avgAmount</code> 为 <code class="literal">null</code> 。
					</p>
			</div>
			<div class="sect2" lang="en-US">
				<div class="titlepage">
					<div>
						<div>
							<h3 class="title"><a id="processingmodel_infra_table"></a>2.14.2. 表</h3>
						</div>
					</div>
				</div>
				<p>EPL中的表不仅仅是某种类型值的持有者。EPL表还是聚合状态的持有者。EPL中的聚合可以是简单的聚合，例如计数、平均值或标准差，但也可以是更丰富的聚合。 更丰富聚合的示例包括事件列表（`window`和`sorted`聚合）或计数最小草图（一组存储近似值的哈希表）。你的应用程序可以轻松扩展并提供自己的聚合。</p>
				<p>由于表列可以作为聚合状态的持有者，它们是更新和访问聚合状态以在语句之间共享的核心位置。下面的图示解释了表如何与聚合状态一起工作。</p>
				<div class="figure">
					<a id="processingmodel_infra_table_drawing"></a>
					<div class="figure-contents">
						<div class="mediaobject" align="center">
							<img src="images/refdoc_procmodel_table.png" align="middle" alt="表到表聚合">
						</div>
					</div>
					<p class="title">
						<b>图2.15. 表到表聚合</b>
					</p>
				</div>
				<br class="figure-break">
					<p>
						<span class="strong"><strong>步骤#1</strong></span>如下创建一个表：
					</p> <pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">
create table AccountAverages(account string primary key, avgAmount avg(double))
    </pre>
					<p>该表以`string`类型的账号作为主键。该表还有一个列，用于存储`double`类型值的平均值。请注意，`create table`不需要知道平均值是如何更新的， 它只需要知道平均值是`double`类型值的平均值。</p>
					<p>作为步骤#1的结果，运行时会分配一个表。在图中，表中为两个不同的账号`0001`和`0002`填充了两行数据。通常表开始时是空的，但我们假设表中已经有行数据。</p>
					<p>为了存储`double`类型值的平均值，运行时必须保存一个计数和一个总和。因此在表的`avgAmount`列中，有用于`count`和`sum`的字段。 对于账号`0001`，假设当前没有值，`count`为零，`sum`为`null`。</p>
					<p>
						<span class="strong"><strong>步骤#2</strong></span>创建一个EPL语句，用于聚合最近10秒内的`Withdrawal`事件：
					</p> <pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">
into table AccountAverages
select avg(amount) as avgAmount
from Withdrawal#time(10)
group by account
    </pre>
					<p>`into table`告诉编译器不要将聚合结果作为语句的一部分本地存储，而是存储到`AccountAverages`表中。`as avgAmount`告诉编译器使用表中的`avgAmount`列。 编译器会检查聚合类型和值类型是否与表列匹配，以及`group by`子句是否与表主键匹配。</p>
					<p>运行时会查找`Withdrawal`事件，并保留一个10秒的时间窗口。通常时间窗口开始时是空的，但图中显示时间窗口中有一些事件。</p>
					<p>
						<span class="strong"><strong>在步骤#3中</strong></span>假设一个`Withdrawal`事件到达，其账号为`0001`，金额为`5000`。运行时将该事件添加到时间窗口中。 运行时会更新表的`avgAmount`列，具体是更新`count`和`sum`这两个字段。它将`count`字段增加1，并将`sum`字段增加`5000`。 如果账号对应的行不存在，运行时会分配一个表行及其列和聚合字段。
					</p>
					<p>
						<span class="strong"><strong>在步骤#4中</strong></span>，即步骤#3发生10秒后，账号为`0001`且金额为`5000`的`Withdrawal`事件离开时间窗口。 运行时会更新表的`avgAmount`列。它将`count`字段减少1，并将`sum`设置为`null`，因为`count`变为零。
					</p>
					<p>其他EPL语句可以通过将表放入`from`子句、使用表访问表达式、`on-action`语句或即发即弃查询来访问表列。</p>
			</div>
			<div class="sect1" lang="en-US">
				<div class="titlepage">
					<div>
						<div>
							<h2 class="title"><a id="processingmodel_aggregation"></a>2.15. 基本聚合语句类型</h2>
						</div>
					</div>
				</div>
				<p>select子句中的表达式、聚合函数的使用以及group-by子句与语句设计相关。 这里的概述尤其与连接、触发语句、输出速率限制和批处理数据窗口相关。</p>
				<div class="itemizedlist">
					<ul>
						<li>
							<p>如果您的语句仅选择聚合值，运行时将输出一行（在连接中可能是零行）。</p>
						</li>
						<li>
							<p>在没有group-by子句的情况下，如果您的语句选择了非聚合值以及聚合值，运行时将为每个事件输出一行。</p>
						</li>
						<li>
							<p>有group-by子句时，如果您的语句选择的非聚合值都在group-by子句中，运行时将为每个组输出一行。</p>
						</li>
						<li>
							<p>有group-by子句时，如果您的语句选择了非聚合值，且并非所有非聚合值都在group-by子句中，运行时将为每个事件输出一行。</p>
						</li>
					</ul>
				</div>
				<p>
					EPL允许每个聚合函数指定其自己的分组标准。更多信息请参见 <a class="xref" href="epl_clauses.html#epl-grouping-agglocal" title="5.6.4. 为每个聚合函数指定分组">第5.6.4节，“为每个聚合函数指定分组”</a>。 文档在 <a class="xref" href="appendix_outputspec.html" title="附录A. 输出参考和示例">附录A, <i>输出参考和示例</i></a> 中提供了语句类型的输出示例，接下来的部分将概述每种语句类型。
				</p>
				<p>
					以下示例假设 <code class="literal">BankInformationWindow</code> 是在其他地方定义的命名窗口。 这些示例使用连接来说明。连接的更多描述请参见 <a class="xref" href="epl_clauses.html#epl-join" title="5.12. 连接事件流">第5.12节，“连接事件流”</a>。
				</p>
				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_aggregation_batch_unagg"></a>2.15.1. 未聚合且未分组</h3>
							</div>
						</div>
					</div>
					<p>未聚合且未分组情况下的示例语句如下：</p>
					<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select * from Withdrawal unidirectional, BankInformationWindow</pre>
					<p>
						当一个 <code class="literal">Withdrawal</code> 事件到来时，输出的行数是 <code class="literal">BankInformationWindow</code> 中的行数。
					</p>
					<p>
						附录在 <a class="xref" href="appendix_outputspec.html#outputspec-simple" title="A.2. 未聚合且未分组语句的输出">第A.2节，“未聚合且未分组语句的输出”</a> 中提供了一个完整的示例，包括随时间变化的输入和输出事件。
					</p>
				</div>
				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_aggregation_batch_full_agg"></a>2.15.2. 完全聚合且未分组</h3>
							</div>
						</div>
					</div>
					<p>如果您的语句仅选择聚合值且不进行分组，您的语句可能如下所示：</p>
					<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select sum(amount) 
from Withdrawal unidirectional, BankInformationWindow</pre>
					<p>
						当一个 <code class="literal">Withdrawal</code> 事件到来时，输出的行数始终为零或一。
					</p>
					<p>
						附录在 <a class="xref" href="appendix_outputspec.html#outputspec-rowforall" title="A.3. 完全聚合且未分组语句的输出">第A.3节，“完全聚合且未分组语句的输出”</a> 中提供了一个完整的示例，包括随时间变化的输入和输出事件。
					</p>
					<p>
						如果任何聚合函数指定了 <code class="literal">group_by</code> 参数和一个维度，例如 <code class="literal">sum(amount, group_by:account)</code> ， 则该语句将作为聚合且分组的语句执行。
					</p>
				</div>
				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_aggregation_batch_event_agg"></a>2.15.3. 聚合且未分组</h3>
							</div>
						</div>
					</div>
					<p>如果您的语句选择了非聚合属性和聚合值，且不进行分组，您的语句可能与此类似：</p>
					<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select account, sum(amount) 
from Withdrawal unidirectional, BankInformationWindow</pre>
					<p>
						当一个 <code class="literal">Withdrawal</code> 事件到来时，输出的行数是 <code class="literal">BankInformationWindow</code> 中的行数。
					</p>
					<p>
						附录在 <a class="xref" href="appendix_outputspec.html#outputspec-aggregateall" title="A.4. 聚合且未分组语句的输出">第A.4节，“聚合且未分组语句的输出”</a> 中提供了一个完整的示例，包括随时间变化的输入和输出事件。
					</p>
				</div>
				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_aggregation_batch_group_agg"></a>2.15.4. 完全聚合且分组</h3>
							</div>
						</div>
					</div>
					<p>如果您的语句选择了聚合值，并且select子句中的所有非聚合属性都列在group by子句中，那么您的语句可能与此示例类似：</p>
					<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select account, sum(amount) 
from Withdrawal unidirectional, BankInformationWindow
group by account</pre>
					<p>
						当一个 <code class="literal">Withdrawal</code> 事件到来时，输出的行数是每个唯一账号对应一行。
					</p>
					<p>
						附录在 <a class="xref" href="appendix_outputspec.html#outputspec-groupedrowpergroup" title="A.5. 完全聚合且分组语句的输出">第A.5节，“完全聚合且分组语句的输出”</a> 中提供了一个完整的示例，包括随时间变化的输入和输出事件。
					</p>
					<p>
						如果任何聚合函数指定了 <code class="literal">group_by</code> 参数和除 <code class="literal">group by</code> 维度之外的其他维度， 例如 <code class="literal">sum(amount, group_by:accountCategory)</code> ，则该语句将作为聚合且分组的语句执行。
					</p>
				</div>
				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_aggregation_batch_event_agg_group"></a>2.15.5. 聚合且分组</h3>
							</div>
						</div>
					</div>
					<p>如果您的语句选择了非聚合属性和聚合值，并且仅使用group by子句对某些属性进行分组，您的语句可能如下所示：</p>
					<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select account, accountName, sum(amount) 
from Withdrawal unidirectional, BankInformationWindow
group by account</pre>
					<p>
						当一个 <code class="literal">Withdrawal</code> 事件到来时，输出的行数是 <code class="literal">BankInformationWindow</code> 中的行数。
					</p>
					<p>
						附录在 <a class="xref" href="appendix_outputspec.html#outputspec-aggregategrouped" title="A.6. 聚合且分组语句的输出">第A.6节，“聚合且分组语句的输出”</a> 中提供了一个完整的示例，包括随时间变化的输入和输出事件。
					</p>
				</div>
			</div>
			<div class="sect1" lang="en-US">
				<div class="titlepage">
					<div>
						<div>
							<h2 class="title"><a id="processingmodel_matchrecognizepattern"></a>2.16. 基本匹配识别模式</h2>
						</div>
					</div>
				</div>
				<p>EPL提供了标准化的匹配识别语法，用于在事件中查找模式。匹配识别模式与正则表达式模式非常相似。</p>
				<p>以下语句是一个匹配识别模式的示例。它检测可能存在于上述声明的命名窗口所保存的事件中的模式。它查找两个紧接的事件，即对于相同来源的事件之间没有其他事件。这两个事件中的第一个必须具有高优先级，第二个事件必须具有中等优先级。</p>
				<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">select * from AlertNamedWindow
  match_recognize (
    partition by origin
    measures a1.origin as origin, a1.alarmNumber as alarmNumber1, a2.alarmNumber as alarmNumber2
    pattern (a1 a2)
    define
      a1 as a1.priority = 'high',
      a2 as a2.priority ='medium'
)</pre>
			</div>
			<div class="sect1" lang="en-US">
				<div class="titlepage">
					<div>
						<div>
							<h2 class="title"><a id="processingmodel_eplpattern"></a>2.17. 基本EPL模式</h2>
						</div>
					</div>
				</div>
				<p>EPL模式语言是一种通用且富有表现力的语法，用于查找多个流的事件之间的时间和属性关系。</p>
				<p>当一个或多个事件发生且与模式的定义匹配时，事件模式以自下而上的方式进行匹配。 模式表达式可以由过滤表达式与模式操作符组合而成。通过将嵌套表达式包含在括号中，表达式可以包含进一步的嵌套模式表达式。</p>
				<p>有五种类型的操作符：</p>
				<div xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="orderedlist">
					<ol>
						<li>
							<p>
								控制模式查找器创建和终止的操作符： <code class="literal">every</code>
							</p>
						</li>
						<li>
							<p>
								逻辑操作符： <code class="literal">and</code> 、 <code class="literal">or</code> 、 <code class="literal">not</code>
							</p>
						</li>
						<li>
							<p>
								对事件顺序进行操作的时间操作符： <code class="literal">-></code> （跟随操作符）
							</p>
						</li>
						<li>
							<p>
								防护条件是导致模式子表达式终止的where条件，例如 <code class="literal">timer:within</code>
							</p>
						</li>
						<li>
							<p>
								观察时间事件的观察者，例如 <code class="literal">timer:interval</code> （间隔观察者）、 <code class="literal">timer:at</code> （类似crontab的观察者）
							</p>
						</li>
					</ol>
				</div>
				<p>一个示例模式，当每一个IBM股票报价的价格大于80且在接下来的60秒内时发出警报：</p>
				<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">every StockTickEvent(symbol="IBM", price>80) where timer:within(60 seconds)</pre>
				<p>一个示例模式，每到整点过五分钟时发出警报：</p>
				<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">every timer:at(5, *, *, *, *)</pre>
				<p>一个示例模式，当事件A发生，接着是事件B或事件C时发出警报：</p>
				<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">A -> ( B or C)</pre>
				<p>一个模式，其中后续事件的一个属性必须与第一个事件的一个属性匹配：</p>
				<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">every a=EventX -> every b=EventY(objectID=a.objectID)</pre>
			</div>
			<div class="sect1" lang="en-US">
				<div class="titlepage">
					<div>
						<div>
							<h2 class="title"><a id="processingmodel_indexes"></a>2.18. 基本索引</h2>
						</div>
					</div>
				</div>
				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_indexes_kinds"></a>2.18.1. 索引种类</h3>
							</div>
						</div>
					</div>
					<p>编译器和运行时会根据语句来规划、构建和维护两种类型的索引：过滤索引和事件索引。</p>
					<p>运行时为了提高效率而构建和维护索引，以实现良好的性能。</p>
					<p>下表比较了这两种索引：</p>
					<div class="table">
						<a id="d0e1788"></a>
						<p class="title">
							<b>表2.2. 索引种类</b>
						</p>
						<div class="table-contents">
							<table summary="Kinds of Indexes" border="1">
								<colgroup>
									<col>
										<col>
											<col>
								</colgroup>
								<thead>
									<tr>
										<th></th>
										<th>过滤索引</th>
										<th>事件索引</th>
									</tr>
								</thead>
								<tbody>
									<tr>
										<td>提高以下操作的速度</td>
										<td>将传入事件与当前活动的、应处理该事件的过滤器进行匹配</td>
										<td>行的查找</td>
									</tr>
									<tr>
										<td>类似于</td>
										<td>结构化的回调注册表；或基于内容的路由</td>
										<td>数据库索引</td>
									</tr>
									<tr>
										<td>索引存储的值</td>
										<td>由表达式提供的值</td>
										<td>某些列的值</td>
									</tr>
									<tr>
										<td>索引指向</td>
										<td>当前活动的过滤器</td>
										<td>行</td>
									</tr>
									<tr>
										<td>可类比为</td>
										<td>一个筛子或一个总机</td>
										<td>一本书中的索引</td>
									</tr>
								</tbody>
							</table>
						</div>
					</div>
					<br class="table-break">
				</div>

				<div class="sect2" lang="en-US">
					<div class="titlepage">
						<div>
							<div>
								<h3 class="title"><a id="processingmodel_indexes_filterindexes"></a>2.18.2. 过滤索引</h3>
							</div>
						</div>
					</div>
					<p>过滤索引对过滤器进行组织，以便能够高效地进行搜索。过滤索引会反向链接到过滤器所来自的语句和分区。</p>
					<p>
						我们使用“过滤器”或“过滤条件”这两个术语来表示选择谓词，例如 <code class="literal">symbol="google" and price > 200 and volume > 111000</code> 。 语句在 <code class="literal">from</code> 子句、EPL 模式和/或上下文声明中提供过滤条件。 请参阅 <a class="xref" href="epl_clauses.html#epl-from-clause-filter" title="5.4.1. 基于过滤的事件流">第 5.4.1 节 “基于过滤的事件流”</a>、<a class="xref" href="event_patterns.html#pattern-filter" title="7.4. 模式中的过滤表达式">第 7.4 节 “模式中的过滤表达式”</a> 和 <a class="xref" href="context.html#context_def_condition_filter" title="4.2.7.1. 过滤上下文条件">第 4.2.7.1 节 “过滤上下文条件”</a>。
					</p>
					<p>
						过滤索引的构建是编译器按照 <a class="xref" href="apicompiler.html#apicompiler-filterplan" title="15.18. 编译器过滤表达式分析">第 15.18 节 “编译器过滤表达式分析”</a> 中所述对过滤表达式进行分析的结果。运行时使用编译器的输出构建、维护和使用过滤索引。
					</p>
					<p>
						关于大 O 符号的缩放信息可以在 <a class="xref" href="performance.html#performance-bigo-filterindex" title="24.1.1. 将事件与语句和上下文分区进行匹配的大 O 复杂度">第 24.1.1 节 “将事件与语句和上下文分区进行匹配的大 O 复杂度”</a> 中找到。
					</p>
					<p>当运行时接收到一个事件时，它会查询过滤索引，以确定哪些语句（如果有的话）必须处理该事件。</p>
					<p>过滤索引的目的是实现：</p>
					<div class="itemizedlist">
						<ul>
							<li>
								<p>仅将事件高效地匹配到需要它们的那些语句。</p>
							</li>
							<li>
								<p>高效地丢弃任何语句都不需要的事件。</p>
							</li>
							<li>
								<p>以最佳情况下大约为 O(1) 到 O(log n) 的复杂度进行高效评估，即最佳情况下，无论输入数据集（即活动过滤器的数量）的大小如何，执行时间大致相同。</p>
							</li>
						</ul>
					</div>
					<p>
						当事件类型出现在 <code class="literal">from</code> 子句或模式中时，运行时会为每种事件类型构建和维护单独的过滤索引集。 过滤索引在同一事件类型过滤器中是可共享的。因此，引用相同事件类型的各种 <code class="literal">from</code> 子句和模式可以为同一组过滤索引做出贡献。
					</p>
					<p>运行时以嵌套方式构建过滤索引：过滤索引可能包含更多的过滤索引，形成一个类似树的结构，即过滤索引树。索引的嵌套超出了此处提供的介绍性讨论范围。</p>
					<div class="sect2" lang="en-US">
						<div class="titlepage">
							<div>
								<div>
									<h3 class="title"><a id="processingmodel_indexes_filterindexes_stmt"></a>2.18.2.1. 过滤索引多语句示例</h3>
								</div>
							</div>
						</div>
						<p>
							语句中的 <code class="literal">from</code> 子句，在特殊情况下还有 <code class="literal">where</code> 子句，会提供过滤条件，编译器会对这些条件进行分析并为其构建过滤索引。
						</p>
						<p>
							例如，假设 <code class="literal">WithdrawalEvent</code> 有一个 <code class="literal">account</code> 字段。你可以创建如下三个语句：
						</p>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">@name('A') select * from WithdrawalEvent(account = 1)</pre>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">@name('B') select * from WithdrawalEvent(account = 1)</pre>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">@name('C') select * from WithdrawalEvent(account = 2)</pre>
						<p>
							在这个例子中，语句 A 和语句 B 都对 <code class="literal">account</code> 值为 1 的 <code class="literal">WithdrawalEvent</code> 事件感兴趣。 语句 C 对 <code class="literal">account</code> 值为 2 的 <code class="literal">WithdrawalEvent</code> 事件感兴趣。
						</p>
						<p>下面的表格是这三个语句的一个示例过滤索引：</p>
						<div class="table">
							<a id="d0e1936"></a>
							<p class="title">
								<b>表 2.3. 示例过滤索引多语句示例</b>
							</p>
							<div class="table-contents">
								<table summary="示例过滤索引多语句示例" border="1">
									<colgroup>
										<col>
											<col>
									</colgroup>
									<thead>
										<tr>
											<th><code class="literal">account</code> 的值</th>
											<th>过滤器</th>
										</tr>
									</thead>
									<tbody>
										<tr>
											<td><code class="literal">1</code></td>
											<td>语句 A，语句 B</td>
										</tr>
										<tr>
											<td><code class="literal">2</code></td>
											<td>语句 C</td>
										</tr>
									</tbody>
								</table>
							</div>
						</div>
						<br class="table-break">
							<p>
								当一个 <code class="literal">Withdrawal</code> 事件到达时，运行时会提取 <code class="literal">account</code> 字段的值，并在上述表格中进行查找。 如果表格中没有匹配的行，例如当 <code class="literal">account</code> 为 3 时，运行时就知道该事件无需进一步处理。
							</p>
							<p>
								在过滤索引规划中，我们使用“可查找表达式”这个术语来表示提供过滤索引查找值的表达式。 在这个例子中，只有一个可查找表达式，即 <code class="literal">account</code> 。 我们使用“值表达式”这个术语来表示提供索引值的表达式。 这里有三个值表达式，分别是 <code class="literal">1</code> （来自语句 A）、 <code class="literal">1</code> （来自语句 B）和 <code class="literal">2</code> （来自语句 C）。 我们使用“过滤索引运算符”这个术语来表示索引的类型，例如等于(=)、关系运算符(&lt;,&gt;,&lt;=, &gt;=) 等。
							</p>
					</div>
					<div class="sect2" lang="en-US">
						<div class="titlepage">
							<div>
								<div>
									<h3 class="title"><a id="processingmodel_indexes_filterindexes_pattern"></a>2.18.2.2. 过滤索引模式示例</h3>
								</div>
							</div>
						</div>
						<p>作为模式的一部分，你可以指定事件类型和过滤条件。编译器会分析模式并确定用于构建过滤索引的过滤条件。</p>
						<p>
							考虑以下示例模式，该模式会为每个 <code class="literal">WithdrawalEvent</code> 触发，前提是该事件之后跟着另一个具有相同 <code class="literal">account</code> 值的 <code class="literal">WithdrawalEvent</code> ：
						</p>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">@name('P') select * from pattern [every w1=WithdrawalEvent -&gt; w2=WithdrawalEvent(account = w1.account)]</pre>
						<p>
							创建上述语句后，运行时开始查找 <code class="literal">WithdrawalEvent</code> 事件。此时只有一个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">WithdrawalEvent</code> 事件的过滤器，不考虑账户 ID。
									</p>
								</li>
							</ul>
						</div>
						<p>
							假设账户 1 的 <code class="literal">WithdrawalEvent</code> W<sub>a</sub> 到达。然后运行时会激活一个查找账户 1 的另一个 <code class="literal">WithdrawalEvent</code> 的过滤器。 此时有两个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">WithdrawalEvent</code> 事件的过滤器，不考虑账户 ID。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">w1</code> =W<sub>a</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
							</ul>
						</div>
						<p>
							假设账户 1 的另一个 <code class="literal">WithdrawalEvent</code> W<sub>b</sub> 到达。然后运行时会激活一个查找账户 1 的另一个 <code class="literal">WithdrawalEvent</code> 的过滤器。 此时有三个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">WithdrawalEvent</code> 事件的过滤器，不考虑账户 ID。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">w1</code> =W<sub>a</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">w2</code> =W<sub>b</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
							</ul>
						</div>
						<p>
							假设账户 2 的另一个 <code class="literal">WithdrawalEvent</code> W<sub>c</sub> 到达。然后运行时会激活一个查找账户 2 的另一个 <code class="literal">WithdrawalEvent</code> 的过滤器。 此时有四个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">WithdrawalEvent</code> 事件的过滤器，不考虑账户 ID。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">w1</code> =W<sub>a</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">w1</code> =W<sub>b</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">w1</code> =W<sub>c</sub> 关联的 <code class="literal">WithdrawalEvent(account=2)</code> 的过滤器。
									</p>
								</li>
							</ul>
						</div>
						<p>
							下面的表格是 W<sub>a</sub>、W<sub>b</sub> 和 W<sub>c</sub> 事件到达后该模式的示例过滤索引：
						</p>
						<div class="table">
							<a id="d0e2164"></a>
							<p class="title">
								<b>表 2.4. 示例过滤索引模式示例</b>
							</p>
							<div class="table-contents">
								<table summary="示例过滤索引模式示例" border="1">
									<colgroup>
										<col>
											<col>
									</colgroup>
									<thead>
										<tr>
											<th><code class="literal">account</code> 的值</th>
											<th>过滤器</th>
										</tr>
									</thead>
									<tbody>
										<tr>
											<td><code class="literal">1</code></td>
											<td>语句 P 模式 <code class="literal">w1</code>=W<sub>a</sub>，语句 P 模式 <code class="literal">w1</code>=W<sub>b</sub></td>
										</tr>
										<tr>
											<td><code class="literal">2</code></td>
											<td>语句 P 模式 <code class="literal">w1</code>=W<sub>c</sub></td>
										</tr>
									</tbody>
								</table>
							</div>
						</div>
						<br class="table-break">
							<p>
								当一个 <code class="literal">Withdrawal</code> 事件到达时，运行时会提取 <code class="literal">account</code> 字段的值，并在上述表格中进行查找。 如果找到匹配的行，运行时可以将该事件传递给相关的模式子表达式。
							</p>
					</div>
					<div class="sect2" lang="en-US">
						<div class="titlepage">
							<div>
								<div>
									<h3 class="title"><a id="processingmodel_indexes_filterindexes_context"></a>2.18.2.3. 过滤索引上下文示例</h3>
								</div>
							</div>
						</div>
						<p>这个示例与之前的多语句示例类似，但它声明了一个上下文，并将单个语句与该上下文相关联。</p>
						<p>
							例如，假设 <code class="literal">LoginEvent</code> 有一个 <code class="literal">account</code> 字段。你可以声明一个由用户的 <code class="literal">LoginEvent</code> 启动的上下文：
						</p>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">@name('A') create context UserSession initiated by LoginEvent as loginEvent</pre>
						<p>
							通过将语句与上下文相关联，你可以让编译器针对每个 <code class="literal">LoginEvent</code> 进行分析，例如：
						</p>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">@name('B') context UserSession select count(*) from WithdrawalEvent(account = context.loginEvent.account)</pre>
						<p>
							创建上述两个语句后，运行时开始查找 <code class="literal">LoginEvent</code> 事件。此时只有一个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">LoginEvent</code> 事件的过滤器（任意账户 ID）。
									</p>
								</li>
							</ul>
						</div>
						<p>
							假设账户 1 的 <code class="literal">LoginEvent</code> L<sub>a</sub> 到达。然后运行时会激活语句 B 的一个上下文分区，因此会激活查找账户 1 的 <code class="literal">WithdrawalEvent</code> 的过滤器。 此时有两个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">LoginEvent</code> 事件的过滤器（任意账户 ID）。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">loginEvent</code> =L<sub>a</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
							</ul>
						</div>
						<p>
							假设账户 1 的 <code class="literal">LoginEvent</code> L<sub>b</sub> 到达。然后运行时会激活语句 B 的一个上下文分区，因此会激活查找账户 1 的 <code class="literal">WithdrawalEvent</code> 的过滤器。 此时有三个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">LoginEvent</code> 事件的过滤器（任意账户 ID）。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">loginEvent</code> =L<sub>a</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">loginEvent</code> =L<sub>b</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
							</ul>
						</div>
						<p>
							假设账户 2 的 <code class="literal">LoginEvent</code> L<sub>c</sub> 到达。然后运行时会激活语句 B 的一个上下文分区，因此会激活查找账户 2 的 <code class="literal">WithdrawalEvent</code> 的过滤器。 此时有四个活动过滤器：
						</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>
										一个查找 <code class="literal">LoginEvent</code> 事件的过滤器（任意账户 ID）。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">loginEvent</code> =L<sub>a</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">loginEvent</code> =L<sub>b</sub> 关联的 <code class="literal">WithdrawalEvent(account=1)</code> 的过滤器。
									</p>
								</li>
								<li>
									<p>
										一个查找与 <code class="literal">loginEvent</code> =L<sub>c</sub> 关联的 <code class="literal">WithdrawalEvent(account=2)</code> 的过滤器。
									</p>
								</li>
							</ul>
						</div>
						<p>下面的表格是三个语句上下文分区的示例过滤索引：</p>
						<div class="table">
							<a id="d0e2380"></a>
							<p class="title">
								<b>表 2.5. 示例过滤索引上下文示例</b>
							</p>
							<div class="table-contents">
								<table summary="示例过滤索引上下文示例" border="1">
									<colgroup>
										<col>
											<col>
									</colgroup>
									<thead>
										<tr>
											<th><code class="literal">account</code> 的值</th>
											<th>过滤器</th>
										</tr>
									</thead>
									<tbody>
										<tr>
											<td><code class="literal">1</code></td>
											<td>语句 B 上下文分区 #0 <code class="literal">loginEvent</code>=L<sub>a</sub>，语句 B 上下文分区 #1 <code class="literal">loginEvent</code>=L<sub>b</sub></td>
										</tr>
										<tr>
											<td><code class="literal">2</code></td>
											<td>语句 B 上下文分区 #2 <code class="literal">loginEvent</code>=L<sub>c</sub></td>
										</tr>
									</tbody>
								</table>
							</div>
						</div>
						<br class="table-break">
							<p>
								当一个 <code class="literal">Withdrawal</code> 事件到达时，运行时会提取 <code class="literal">account</code> 字段的值，并在上述表格中进行查找。 然后它可以将事件直接传递给相关的语句上下文分区，如果对于给定的账户 ID 没有找到匹配的行，则会忽略该事件。
							</p>
					</div>
					<div class="sect2" lang="en-US">
						<div class="titlepage">
							<div>
								<div>
									<h3 class="title"><a id="processingmodel_indexes_eventindexes"></a>2.18.3. 事件索引</h3>
								</div>
							</div>
						</div>
						<p>事件索引对某些列进行组织，以便能够高效地进行搜索。事件索引会反向链接到列所来自的行。</p>
						<p>
							关于大 O 符号的缩放信息可以在 <a class="xref" href="performance.html#performance-bigo-select" title="24.1.3. 连接、子查询、On-Select、On-Merge、On-Update、On-Delete 的大 O 复杂度">第 24.1.3 节 “连接、子查询、On-Select、On-Merge、On-Update、On-Delete 的大 O 复杂度”</a> 中找到。
						</p>
						<p>由于事件索引与数据库索引类似，在本次讨论中，我们使用“列”这个术语来表示 EPL 表或命名窗口中的列，同时也表示事件属性或字段。 我们使用“行”这个术语来表示 EPL 表或命名窗口中的行，同时也表示一个事件。</p>
						<p>当运行时执行语句处理时，它可能会使用事件索引来高效地找到相关的行。</p>
						<p>事件索引的目的是实现：</p>
						<div class="itemizedlist">
							<ul>
								<li>
									<p>高效地评估子查询。</p>
								</li>
								<li>
									<p>高效地评估连接操作。</p>
								</li>
								<li>
									<p>高效地评估 on-action 语句。</p>
								</li>
								<li>
									<p>高效地评估即发即弃查询。</p>
								</li>
							</ul>
						</div>
						<p>
							事件索引的构建是编译器分析连接的 <code class="literal">where</code> 子句关联条件（外连接的 <code class="literal">on</code> 子句）、子查询、on-action 和即发即弃查询的结果。 这是由编译器自动完成的。你可以使用 <code class="literal">create index</code> 子句来显式地为命名窗口和表建立索引。你可以使用查询规划器提示来影响索引的构建、使用和共享。
						</p>
					</div>
					<div class="sect1" lang="en-US">
						<div class="titlepage">
							<div>
								<div>
									<h2 class="title"><a id="processingmodel_3valuedlogic"></a>2.19. 基本空值</h2>
								</div>
							</div>
						</div>
						<p>
							EPL 和 SQL 使用三值逻辑：除了 <code class="literal">true</code> 和 <code class="literal">false</code> 之外，表达式的结果也可以是未知的。三值逻辑是支持使用 <code class="literal">null</code> 来标记缺失数据的结果。 如果一个 <code class="literal">null</code> 值影响了逻辑表达式的结果，那么结果既不是 <code class="literal">true</code> 也不是 <code class="literal">false</code> ，而是未知的。
						</p>
						<p>
							一个 <code class="literal">null</code> 值基本上意味着“可能是任何值”。因此，无法判断与 <code class="literal">null</code> 的比较结果是 <code class="literal">true</code> 还是 <code class="literal">false</code> 。 这就是第三个逻辑值“未知”的由来。未知意味着“可能是 true 或 false，取决于 null 值”。
						</p>
						<p>
							因此，以下每个比较的结果都是 <code class="literal">null</code> （未知）：
						</p>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">null = 1</pre>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">null &lt;&gt; 1</pre>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">null &gt; 1</pre>
						<pre xmlns="" xmlns:d="http://docbook.org/ns/docbook" xmlns:rf="java:org.jboss.highlight.XhtmlRendererFactory" class="">null = null</pre>
						<p>
							没有任何值 <span class="emphasis"><em>等于</em></span> null。甚至 <code class="literal">null</code> 也不等于 <code class="literal">null</code> ，因为每个 <code class="literal">null</code> 可能是不同的。 这就是为什么 EPL 有 <code class="literal">is null</code> 谓词来测试一个值是否为 null。
						</p>
						<p>
							鸣谢：以上内容摘自一篇在线文本，可在 <a class="link" href="http://modern-sql.com/concept/three-valued-logic" target="">http://modern-sql.com/concept/three-valued-logic</a> 找到。
						</p>
					</div>
					<ul xmlns:d="http://docbook.org/ns/docbook" class="docnav">
						<li class="previous"><a accesskey="p" href="gettingstarted.html"><strong>上一页</strong>第 1 章. 入门</a></li>
						<li class="up"><a accesskey="u" href="#"><strong>返回顶部</strong></a></li>
						<li class="home"><a accesskey="h" href="index.html"><strong>首页</strong></a></li>
						<li class="next"><a accesskey="n" href="event_representation.html"><strong>下一页</strong>第 3 章. 事件表示</a></li>
					</ul>
</body>

</html>